Skip to content

fix(reborn): re-thread provider_factory through the cold-boot gateway (#6174 regression) - #6300

Merged
ilblackdragon merged 2 commits into
mainfrom
fix/reborn-provider-factory-seam
Jul 20, 2026
Merged

ilblackdragon merged 2 commits into
mainfrom
fix/reborn-provider-factory-seam

Conversation

@ilblackdragon

Copy link
Copy Markdown
Member

What

Re-thread the caller-supplied provider_factory (the LLM instrumentation seam)
through the reborn cold-boot gateway so ResolvedRebornLlm::with_provider_factory
is honored again.

Why

#6174 turned with_provider_factory into dead code. That PR moved reborn
boot to always build the placeholder LLM gateway and swap the real provider in
via a post-construction RebornLlmReloadAdapter::reload. In the process:

  • build_production_model_gateway() stopped taking the resolved LLM, and
  • build_placeholder_llm_gateway() hardcoded None into wrap_swappable_gateway.

So the factory carried on ResolvedRebornLlm was set but never read on any
production path (only a unit test passed Some). The helper worked; nothing
called it with a factory.

That factory is how nearai-bench (--framework ironclaw-reborn) wraps the
provider in InstrumentedLlm to capture tokens / reasoning / cost. With it
dropped, every claw-swe-bench-lite task fails immediately with 0 model
calls
:

reborn run failed: reborn provider factory never ran (no instrumented provider)

i.e. the benchmark cannot measure latest main at all.

Fix

Thread the resolved LLM's provider_factory through
build_production_model_gateway → build_placeholder_llm_gateway →
wrap_swappable_gateway. It wraps the swappable provider, so it stays in
the call path across the boot-time reload that swaps a real provider into the
placeholder — the reload-stable contract already documented on
wrap_swappable_gateway and covered by provider_factory_survives_live_reload.

No new types, traits, or dependency edges: this threads one existing
pub(crate) field through two private fns.

Tests

New regression test drives the real caller (build_reborn_runtime), which
is exactly the gap that let the regression through — the existing
provider_factory_survives_live_reload only exercised the
wrap_swappable_gateway helper directly, so it could not catch a boot path that
never calls the helper with Some:

  • provider_factory_runs_during_production_boot — asserts the factory is
    invoked once during boot. Fails on the pre-fix path (helper called with
    None), passes with the fix. Verified red→green locally.

Also refreshes stale docs referencing the removed build_llm_gateway.

Validation

  • cargo clippy -p ironclaw_reborn_composition --all-targets across
    all-features / default / libsql-only, -D warnings — clean.
  • cargo test -p ironclaw_reborn_composition --all-features — green.
  • cargo test -p ironclaw_architecture — green (no boundary changes).

🤖 Generated with Claude Code

…#6174 regression)

#6174 collapsed the reborn boot path to always build the placeholder LLM
gateway and swap the real provider in via a post-construction reload. That
dropped the `ResolvedRebornLlm::provider_factory` threading:
`build_production_model_gateway` took no factory and
`build_placeholder_llm_gateway` hardcoded `None` into `wrap_swappable_gateway`,
so `ResolvedRebornLlm::with_provider_factory` became dead — the field was set
but never read on any production path (only a unit test passed `Some`).

That factory is the instrumentation seam the benchmark harness (nearai-bench,
`--framework ironclaw-reborn`) uses to wrap the provider in `InstrumentedLlm`
for token/reasoning/cost capture. With it silently dropped, every
claw-swe-bench-lite task failed instantly with 0 model calls
("reborn provider factory never ran (no instrumented provider)"), tanking the
score to noise.

Thread the resolved LLM's `provider_factory` through
build_production_model_gateway -> build_placeholder_llm_gateway ->
wrap_swappable_gateway. It wraps the *swappable* provider, so it stays in the
call path across the boot-time reload — the reload-stable contract already
documented on `wrap_swappable_gateway` and covered by
`provider_factory_survives_live_reload`.

Regression test drives the real caller (`build_reborn_runtime`), not just the
helper: `provider_factory_runs_during_production_boot` asserts the factory is
invoked once during boot. It fails on the pre-fix boot path (helper called with
`None`) and passes with the fix.

Also refreshes stale docs that referenced the removed `build_llm_gateway`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ironloopai

ironloopai Bot commented Jul 20, 2026 •

Copy link
Copy Markdown
Contributor

🔎 IronLoop Review Status

Head: 090572c224f326128ff6419887ae5d1e332e6416
Result: Reviewer output needs human attention or validation.
Next: Review the flagged rows before merging.
Updated: 2026-07-20T03:47:28.470Z

Current reviewers:

Reviewer State Verdict Findings Last update
ironloop/common-reviewer (reviewer) Completed Needs validation 0 blocking findings / 0 notes; needs validation 2026-07-20T03:47:28.461Z
Reviewer summaries
Reviewer Detail
ironloop/common-reviewer (reviewer) Needs validation; 0 blocking findings; Static review found the provider factory is threaded through every production gateway call and remains outside the swappable provider across boot-time reloads. The new caller-leve…
Recent activity
Time Reviewer State Detail
2026-07-20T02:39:42.600Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
2026-07-20T03:35:41.377Z ironloop/common-reviewer (reviewer) Superseded A newer PR head replaced this review (090572c).
2026-07-20T03:44:52.686Z ironloop/common-reviewer (reviewer) Queued Accepted review request for head 090572c.
2026-07-20T03:44:52.686Z ironloop/common-reviewer (reviewer) Queued Waiting for this reviewer lane to become available.
2026-07-20T03:44:52.811Z ironloop/common-reviewer (reviewer) Started Reviewer worker started.
2026-07-20T03:44:56.200Z ironloop/common-reviewer (reviewer) Workspace ready Prepared isolated checkout (merge_ref) at 98c0967.
2026-07-20T03:47:28.461Z ironloop/common-reviewer (reviewer) Result captured Needs validation; 0 blocking findings.
2026-07-20T03:47:28.461Z ironloop/common-reviewer (reviewer) Completed Review completed and terminal status was persisted.
Available commands
  • @ironloopai help
  • @ironloopai agents
  • @ironloopai review
  • @ironloopai review --agent <agent>
Run metadata

Admission: webhook accepted the request and IronLoop persisted reviewer state before this projection.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6300 July 20, 2026 02:37 Destroyed
@github-actions github-actions Bot added size: M 50-199 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jul 20, 2026
@coderabbitai

coderabbitai Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ad14473e-54cb-4a5f-9b60-92dbfbc75be2

📥 Commits

Reviewing files that changed from the base of the PR and between fd7614f and 090572c.

📒 Files selected for processing (3)
  • crates/ironclaw_reborn_composition/src/runtime.rs
  • crates/ironclaw_reborn_composition/src/runtime/tests/core.rs
  • crates/ironclaw_reborn_composition/src/runtime_input.rs

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Preserved the optional provider instrumentation/decorator across Reborn runtime cold boot and subsequent live provider reloads.
  • Tests
    • Added a regression test to confirm the provided provider-factory closure is invoked during production startup.
  • Documentation
    • Updated docs to clarify that provider instrumentation is applied over the swappable gateway path and persists through boot-time reloads.

Walkthrough

The Reborn runtime now preserves an optional provider factory through production cold boot, placeholder gateway creation, and swappable gateway setup. A regression test verifies invocation during boot, and documentation describes the retained wrapper behavior.

Changes

Provider factory boot preservation

Layer / File(s) Summary
Thread provider factory through boot gateways
crates/ironclaw_reborn_composition/src/runtime.rs
build_reborn_runtime passes the provider factory through production and placeholder gateway construction into wrap_swappable_gateway.
Validate and document boot preservation
crates/ironclaw_reborn_composition/src/runtime/tests/core.rs, crates/ironclaw_reborn_composition/src/runtime_input.rs
A production-boot test verifies one factory invocation, while comments and documentation describe swappable-wrapper preservation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: henrypark133

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description has useful detail but misses required template sections like Change Type, Linked Issue, Security Impact, and the Reborn checklist. Rewrite the PR body to match the repo template and fill all required sections, especially Change Type, Linked Issue, Validation, Security Impact, and Rollback Plan.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is conventional-commit styled and accurately summarizes the cold-boot provider_factory regression fix.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request ensures that the caller's optional instrumentation decorator (provider_factory) is correctly threaded into the cold-boot gateway during build_reborn_runtime instead of being silently dropped. It updates build_production_model_gateway and build_placeholder_llm_gateway to accept and propagate this factory, updates relevant documentation, and adds a regression test (provider_factory_runs_during_production_boot) to verify this behavior. There are no review comments to address, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@ironloopai ironloopai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ IronLoop Review: reviewer

Review at a glance

Verdict Blocking Notes Inline Head
⚠️ Needs validation 0 0 0 fd7614ff2350

Head: fd7614ff23506a8a6bd75a81d1d063396617bad7
Next: Human review or validation is required before merging.

Run details

Status: Current
Needs human: no
Needs validation: yes

Summary

No concrete correctness or security issue found in the focused cold-boot factory threading change. Runtime validation could not run because this environment has no Rust toolchain.

Findings

None.

Developer follow-up

After fixing this feedback:

  1. Push the fix to this PR branch.
  2. Re-run this reviewer with @ironloopai review --agent reviewer if you only changed this reviewer's findings.
  3. Re-run all reviewers with @ironloopai review when the fix may affect multiple areas.

@railway-app

railway-app Bot commented Jul 20, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the ironclaw-pr-6300 environment in ironclaw-ci-preview

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 20, 2026 at 3:51 am

@ilblackdragon

Copy link
Copy Markdown
Member Author

✅ Ready for merge.

Reviewed the cold-boot factory re-threading and ran the validation IronLoop's toolchain-less env couldn't:

Review — correct and well-scoped. #6174 collapsed the boot path to build_placeholder_llm_gateway() with a hardcoded None factory, silently dropping ResolvedRebornLlm::with_provider_factory on the production path. This re-threads boot_provider_factory — a cheap Arc clone taken from the shared llm borrow (correctly .as_ref().and_then(|r| r.provider_factory.clone()), not a move-out) — through build_production_model_gateway → build_placeholder_llm_gateway → wrap_swappable_gateway, so the instrumentation decorator wraps the swappable and survives the boot-time reload. Both cfg branches (test-support + production) are updated consistently.

Test is exactly right. provider_factory_runs_during_production_boot drives the real caller (build_reborn_runtime), not the helper — so unlike the existing provider_factory_survives_live_reload (which calls wrap_swappable_gateway directly), it catches a boot path that never invokes the helper with a factory at all. Textbook test-through-the-caller for the exact #6174 regression.

Validation (IronLoop couldn't — no Rust toolchain in its env):

  • cargo test -p ironclaw_reborn_composition --features test-support,libsql,root-llm-provider provider_factory_runs_during_production_boot → passes (factory invoked exactly once at boot).
  • cargo clippy -p ironclaw_reborn_composition --features test-support,libsql --all-targets → clean, zero warnings.

IronLoop: 0 blocking, 0 notes, 0 findings. CI green (52 pass, 0 fail).

@github-actions

github-actions Bot commented Jul 20, 2026 •

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 86.2% (319514 / 370673 lines)
  floor:    85.3% (tolerance 0.5pp -> effective floor 84.8%)
  denominator: 370673 lines now vs 320188 at floor capture (+50485 lines, +15.77%) — material change (>5%)

⚠️ 2 Reborn crate(s) have 0 int-tier coverage (target: 0) — ironclaw_prompt_envelope, ironclaw_scripts

Reborn integration-tier coverage

Line coverage (Reborn crates): 86.2% — 319514 / 370673 lines

Per-crate breakdown (65 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_prompt_envelope 0% 0 / 88
ironclaw_scripts 0% 0 / 345
ironclaw_runtime_policy 33.84% 89 / 263
ironclaw_event_projections 43.31% 673 / 1554
ironclaw_observability 61.54% 16 / 26
ironclaw_authorization 62.46% 604 / 967
ironclaw_dispatcher 62.88% 83 / 132
ironclaw_mcp 64.89% 595 / 917
ironclaw_triggers 65.44% 2142 / 3273
ironclaw_filesystem 67.78% 3957 / 5838
ironclaw_channel_host 68.65% 219 / 319
ironclaw_memory 69.2% 773 / 1117
ironclaw_reborn_migration 71.64% 1551 / 2165
ironclaw_trust 72.88% 661 / 907
ironclaw_wasm_limiter 74.6% 47 / 63
ironclaw_reborn_event_store 74.67% 958 / 1283
ironclaw_extractors 74.72% 538 / 720
ironclaw_capabilities 75.72% 2096 / 2768
ironclaw_projects 76.48% 400 / 523
ironclaw_reborn_cli 77% 10247 / 13307
ironclaw_llm 78.36% 20306 / 25915
ironclaw_product_context 78.57% 11 / 14
ironclaw_telegram_extension 80.18% 4842 / 6039
ironclaw_wasm_product_adapters 80.36% 1448 / 1802
ironclaw_process_sandbox 80.65% 671 / 832
ironclaw_first_party_extensions 81.06% 5965 / 7359
ironclaw_memory_native 81.17% 3195 / 3936
ironclaw_events 81.95% 1594 / 1945
ironclaw_network 82.98% 673 / 811
ironclaw_reborn_identity 83.59% 433 / 518
ironclaw_processes 83.76% 939 / 1121
ironclaw_secrets 83.79% 2548 / 3041
ironclaw_wasm 84.44% 1069 / 1266
ironclaw_auth 84.81% 3233 / 3812
ironclaw_product_workflow 84.91% 11031 / 12992
ironclaw_reborn_config 85.2% 2055 / 2412
ironclaw_run_state 85.61% 458 / 535
ironclaw_channel_delivery 85.79% 1383 / 1612
ironclaw_common 86.13% 1714 / 1990
ironclaw_turns 86.7% 14703 / 16958
ironclaw_threads 86.93% 4708 / 5416
ironclaw_slack_v2_adapter 87.3% 1491 / 1708
ironclaw_skills 87.58% 4470 / 5104
ironclaw_product_adapter_registry 88.06% 531 / 603
ironclaw_product_adapters 88.1% 3384 / 3841
ironclaw_reborn_traces 88.2% 11946 / 13544
ironclaw_hooks 88.35% 10075 / 11404
ironclaw_host_api 88.65% 4389 / 4951
ironclaw_host_runtime 88.69% 18060 / 20363
ironclaw_reborn_openai_compat 89.21% 3778 / 4235
ironclaw_webui 89.33% 7700 / 8620
ironclaw_extensions 89.38% 2971 / 3324
ironclaw_runner 89.65% 17454 / 19469
ironclaw_telegram_v2_adapter 89.7% 2717 / 3029
ironclaw_reborn_composition 90.09% 74866 / 83100
ironclaw_approvals 90.18% 1598 / 1772
ironclaw_conversations 90.39% 3123 / 3455
ironclaw_event_streams 90.82% 1009 / 1111
ironclaw_resources 91.65% 4476 / 4884
ironclaw_loop_host 92.28% 15997 / 17336
ironclaw_attachments 93.06% 630 / 677
ironclaw_agent_loop 94.95% 9416 / 9917
ironclaw_safety 95.09% 3682 / 3872
ironclaw_outbound 95.52% 3451 / 3613
ironclaw_first_party_extension_ports 95.62% 3672 / 3840

This table itself is informational and never gates the PR on its own — not the percentage, not the per-crate holes, not the 0-coverage callout. A separate coverage ratchet (dry-run until enforce=true; see tests/integration/coverage-floor.toml) can fail the build on specific configured floors.

Exemptions (3 entry/entries excluded from the accounting above)
Module / Crate Reason Issue
crate: ironclaw_embeddings v1-only: consumed only by root ironclaw (src/app.rs, src/tools/builtin/memory.rs, src/workspace/mod.rs, src/config/{mod,embeddings}.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_gateway v1-only: consumed only by root ironclaw (src/channels/web/platform/static_files.rs, src/channels/web/handlers/frontend.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_tui v1-only: consumed only by root ironclaw (src/main.rs, src/channels/tui.rs); no crates/* dependents. Crate's own doc comment confirms it bridges INTO v1, not Reborn. Covered by "Tests (Legacy)". #5657

henrypark133
henrypark133 previously approved these changes Jul 20, 2026
@henrypark133
henrypark133 added this pull request to the merge queue Jul 20, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Jul 20, 2026
Reconcile the cold-boot provider_factory threading with main's deletion of the
`root-llm-provider` feature (landed via the §5.3 collapse, #6299): drop the now-
dead `#[cfg(feature = "root-llm-provider")]` gates while keeping the factory
threaded unconditionally through build_production_model_gateway →
build_placeholder_llm_gateway → wrap_swappable_gateway. Un-gate the
provider_factory_runs_during_production_boot regression test (its feature is
gone) and refresh the runtime_input doc.

Verified: composition compiles (test-support,libsql and libsql-only/production);
provider_factory_runs_during_production_boot runs + passes; clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6300 July 20, 2026 03:35 Destroyed
@ilblackdragon

Copy link
Copy Markdown
Member Author

Merge with main resolved (reconciled the provider_factory threading against main's root-llm-provider deletion); the provider_factory_runs_during_production_boot regression test runs + passes on the merged head, clippy clean. @ironloopai review

@ironloopai ironloopai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ IronLoop Review: reviewer

Review at a glance

Verdict Blocking Notes Inline Head
⚠️ Needs validation 0 0 0 090572c224f3

Head: 090572c224f326128ff6419887ae5d1e332e6416
Next: Human review or validation is required before merging.

Run details

Status: Current
Needs human: no
Needs validation: yes

Summary

Static review found the provider factory is threaded through every production gateway call and remains outside the swappable provider across boot-time reloads. The new caller-level regression covers the previously missing forwarding branch; no actionable code findings found.

Findings

None.

Developer follow-up

After fixing this feedback:

  1. Push the fix to this PR branch.
  2. Re-run this reviewer with @ironloopai review --agent reviewer if you only changed this reviewer's findings.
  3. Re-run all reviewers with @ironloopai review when the fix may affect multiple areas.

@ilblackdragon

Copy link
Copy Markdown
Member Author

✅ Ready for merge. Merge-with-main conflicts resolved (reconciled the cold-boot provider_factory threading against main's root-llm-provider feature deletion; un-gated the now-featureless regression test). CI fully green (0 fail); IronLoop re-reviewed the merged head 090572c2 with 0 findings (validation-only). provider_factory_runs_during_production_boot runs + passes on the merged head; clippy + fmt clean.

@ilblackdragon
ilblackdragon merged commit 8aa7cfd into main Jul 20, 2026
65 checks passed
@ilblackdragon
ilblackdragon deleted the fix/reborn-provider-factory-seam branch July 20, 2026 04:13

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-6300 — 090572c2 Deployed Jul 20, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: low Changes to docs, tests, or low-risk modules size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants